package trunk.grupo4Practico2.src;

import java.util.ArrayList;

public class TLista implements ILista {
	// ATRIBUTOS---------------
	private IElemento primero;
	private int cantidadElementos;
	public TLista(){
		primero = null;
		cantidadElementos=0 ;

	}
	
	// ------------------------

	// ENCAPSULAMOS------------------
	public IElemento getPrimero() {
		return primero;
	}

	public void setPrimero(IElemento primero) {
		this.primero = primero;
	}

	// ------------------------------

	// METODOS-----------------------
	/**
	 * Metodo: constructor
	 * 
	 * Funcion: El objetivo del constructor es el de inicializar un objeto de la
	 * clase TLista cuando éste es creado. Asignaremos los valores iniciales:
	 * primero.
	 * 
	 */
	public TLista(IElemento primero) {
		cantidadElementos=0 ;
		this.primero = primero;
	}

	/**
	 * Metodo: insertarAlFinal
	 * 
	 * Funcion: Inserta elemento al final de la lista
	 * 
	 * @author grupo4
	 */
	@Override
	public boolean insertarAlFinal(IElemento elemento) {
		IElemento eleActual;
		eleActual = primero;
		if (esVacia()) {
			primero = elemento;
			cantidadElementos++;
			return (primero == elemento);
		}
		while (eleActual.getSiguiente() != null) {
			eleActual = eleActual.getSiguiente();
		}
		eleActual.setSiguiente(elemento);
		cantidadElementos++;
		return (eleActual.getSiguiente() == elemento);
	}

	public boolean esVacia() {
		return (primero == null);
	}

	/**
	 * Metodo: insertarAlPrincipio
	 */
	@Override
	public boolean insertarAlPrincipio(IElemento elemento) {
		elemento.setSiguiente(primero);
		cantidadElementos++;
		primero = elemento;
		return (primero == elemento);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public IElemento buscar(Comparable clave) {
		IElemento eleActual= primero; 
		if (esVacia()) {
			return null;
		}

		while (eleActual != null
				&& eleActual.getEtiqueta().compareTo(clave) != 0) {
			eleActual = eleActual.getSiguiente();
		}

		return eleActual;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public IElemento eliminar(Comparable clave) {
		if (buscar(clave)== null){
			return null;
		}
		IElemento eleAnterior = primero;
		IElemento eleActual = eleAnterior.getSiguiente();
		if (!esVacia()) {
			if (eleAnterior.getEtiqueta().compareTo(clave)==0) {
				IElemento eleADevolver = eleAnterior;
				primero = eleActual;
				eleAnterior.setSiguiente(null);
				cantidadElementos--;
				return eleADevolver;
			} else {
			}
			while (eleActual != null) {

				if (eleActual.getEtiqueta().compareTo(clave) != 0) {
					eleAnterior = eleActual;
					eleActual = eleActual.getSiguiente();
				} else {
					eleAnterior = eleActual.getSiguiente();
					eleActual.setSiguiente(null);
					IElemento eleADevolver = eleActual;
					cantidadElementos--;
					return eleADevolver;
				}
			}

		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean insertarOrdenado(IElemento elemento) {
		if (elemento == null){
			return false;
		}
		else if (primero == null || (primero.getEtiqueta().compareTo(elemento.getEtiqueta())>0)){
			return insertarAlPrincipio(elemento);
		}
		else{
			IElemento elementoAnterior = null;
			IElemento elementoActual = primero;
			while (elementoActual != null && (elementoActual.getEtiqueta().compareTo(elemento.getEtiqueta()))<0){
				elementoAnterior = elementoActual;
				elementoActual = elementoActual.getSiguiente();
			}
			elementoAnterior.setSiguiente(elemento);
			elemento.setSiguiente(elementoActual);
			cantidadElementos++;
			//cantidadelementos++;
			return true;
		}
	}
	@Override
	public String imprimirElementos() {
		IElemento recorre = primero;
		String adevolver="";
		while (recorre != null) {
			System.out.println(recorre.getEtiqueta());
			adevolver+=recorre.getEtiqueta()+",";
			recorre = recorre.getSiguiente();
		}
		if (!adevolver.equals(""))
			return  adevolver.substring(0, adevolver.length()-1);
		else 
			return adevolver;
			
	}

	/**
	 * Metodo: Eliminar Duplicados
	 * 
	 * Funcion: Elimina los duplicados de la lista, de forma tal que crea una
	 * lista auxiliar, y va insertando los elementos verificando que dichos
	 * elementos no se encuentren ya en la lista auxiliar y los va eliminando de
	 * la lista original cuando la lista original quede vacia, referenciamos al
	 * primer objeto de nuestra lista original como el primer objeto de la lista
	 * auxiliar sin duplicados.
	 * 
	 * @author group 4
	 * 
	 * @return boolean
	 */
	public boolean eliminarDuplicados() {
		TLista auxiliar = new TLista(null);
		boolean esIgual = false;
		while (!esVacia()) {
			if (auxiliar.esVacia()) {
				auxiliar.insertarAlPrincipio(primero);
				primero = primero.getSiguiente();
			} else {
				IElemento recorreAuxiliar = auxiliar.getPrimero();
				while (recorreAuxiliar != null) {
					if (recorreAuxiliar != primero) {
						recorreAuxiliar = recorreAuxiliar.getSiguiente();
						esIgual = false;
					} else {
						esIgual = true;
						recorreAuxiliar = null;
					}
				}
				if (esIgual == false) {
					auxiliar.insertarAlPrincipio(primero);
					primero = primero.getSiguiente();
				} else {
					primero = primero.getSiguiente();
				}
			}
		}
		if (esVacia() && !auxiliar.esVacia()) {
			this.primero = auxiliar.getPrimero();
			return true;
		} else {
			return false;
		}
	}

	@Override
	public int obtenerCantidadElementos() {
		return cantidadElementos;
	}
}
